package main

import (
	"fmt"
	"os"
	"strconv"
)

type CLI struct {
	bc *BlockChain
}

func (cli *CLI) Run() {
	args := os.Args
	if len(args) < 2 {
		fmt.Println("命令行错误")
	}
	cmd := args[1]
	switch cmd {
	case "addBlock":
		fmt.Println("添加区块")
		if len(args) == 4 && args[2] == "--data" {
			data := args[3]
			cli.AddBlock(data)
		} else {
			fmt.Println("添加区块使用参数不正确")
		}
	case "printChain":
		cli.PrintBlockChain()
	case "getBalance":
		fmt.Println("获取余额")
		if len(args) == 4 && args[2] == "--address" {
			address := args[3]
			cli.GetBalance(address)
		}
	case "send":
		fmt.Println("转账开始...")
		if len(args) != 7 {
			fmt.Println("参数个数错误,请检查!")
		}
		from := args[2]
		to := args[3]
		amount, _ := strconv.ParseFloat(args[4], 4)
		miner := args[5]
		data := args[6]
		cli.Send(from, to, amount, miner, data)
	case "newWallet":
		fmt.Println("创建钱包")
		cli.NewWallet()
	case "addAddress":
		fmt.Println("创建地址")
		cli.AddAddress()
	case "listAddresses":
		fmt.Println("列举所有的钱包地址")
		cli.ListAddresses()
	default:
		fmt.Println("命令行错误")
	}
}

func (cli *CLI) AddBlock(data string) {
	//cli.bc.AddBlock(Transaction{}})
}

// ./btc3 printChain
func (cli *CLI) PrintBlockChain() {
	bc := cli.bc
	it := bc.NewIterator()
	var i int
	for {
		i++
		block := it.next()
		fmt.Printf("前一个区块的哈希值为 %x\n", block.PrevHash)
		fmt.Printf("当前的区块的哈希值为 %x\n", block.Hash)
		fmt.Printf("当前的区块的数据为 %s\n", block.Transactions[0].TXInputs[0].Sig)
		if len(block.PrevHash) == 0 {
			fmt.Println("区块链遍历结束")
			break
		}
	}
	fmt.Printf("区块链的总数是%d", i)
}

// ./btc3 getBalance --address dong
func (cli *CLI) GetBalance(address string) {
	var utmost = cli.bc.FindUTXOs(address)
	total := 0.0
	for _, utop := range utmost {
		total += utop.Value
	}
	fmt.Printf("%s的余额为:%f\n", address, total)
}

// ./btc3 send dong wang 10 nmgdl test
func (cli *CLI) Send(from, to string, amount float64, miner, data string) {
	fmt.Printf("from : %s\n", from)
	fmt.Printf("to:%s\n", to)
	fmt.Printf("amount:%f\n", amount)
	fmt.Printf("miner:%s\n", miner)
	fmt.Printf("data:%s\n", data)
	coinbase := NewCoinbaseTX(miner, data)
	tx := NewTransaction(from, to, amount, cli.bc)
	if tx != nil {
		cli.bc.AddBlock([]*Transaction{coinbase, tx})
	}
	fmt.Printf("转账成功!")
}

// ./btc3 newWallet
func (cli *CLI) NewWallet() {
	ws := NewWallets()
	address := ws.CreateWallet()
	fmt.Printf("地址:%s\n", address)
}

// ./btc3 addAddress
func (cli *CLI) AddAddress() {
	ws := NewWallets()
	address := ws.CreateAddress()
	fmt.Printf("地址:%s\n", address)
}

// ./btc3 listAddresses
func (cli *CLI) ListAddresses() {
	var ws Wallets
	ws.WalletsMap = make(map[string]*Wallet)
	ws.loadFile()
	address := ws.GetAllAddresses()
	fmt.Println(address)
}
